<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   
</body>
<script>
    /**
     * 首先，null像在Java里一样，被当成一个对象。但是，JavaScript的数据类型分成原始类型（primitive）和合成类型（complex）两大类，
     * Brendan Eich觉得表示"无"的值最好不是对象。
     * 其次，JavaScript的最初版本没有包括错误处理机制，发生数据类型不匹配时，往往是自动转换类型或者默默地失败。
     * 如果null自动转为0，很不容易发现错误
     * 
     * null 表示 “没有对象”，该处不应该有值
     * null：表示一个空值或者没有对象的引用。在代码中，可以将 null 赋值给一个变量，来显式地指示这个变量的值为空。
     * 
     * undefined表示“缺少值”，该处应该有值，但是还没有被定义
     * undefined：表示一个未定义的值，即一个变量已经声明但没有被赋值，或者一个属性不存在于对象中。在 JavaScript 中，
     * 当访问一个未初始化的变量时，或者访问一个对象中不存在的属性时，其值为 undefined。
     * 转换数值不同，null转换为数值是 0 ,undefined转换为数值是NAN
     * 
     * 区别：


        当一个变量被声明但未赋值时，它的默认值为 undefined。
        null 是一个表示空值的特殊值，可以赋值给任何类型的变量，而 undefined 是一个表示未定义的特殊值。
        在进行类型比较时，null 和 undefined 并不严格相等，即 null === undefined 的结果为 false，
        但在非严格比较中（例如 null == undefined），它们会被认为是相等的。
     * 
    */
    let car = null
   console.log('car', typeof car)
   console.log(null == undefined)
   // 出现undefined的情况
   // （1） 声明了变量，但是没有赋值
   let a;
   console.log('a', a)
   // (2)对象某个属性不存在
   let obj = {}
   console.log('obj', obj.a)
   //(3) 函数的调用少了参数
   function fun (a, b) {
    console.log('fun', a, b)
   }
   fun(3)
   //（4）常规函数默认返回的值
    function fun1 () {
        console.log('1,2,3')
    }
    console.log('fun1', fun1())
    // 出现null的情况
    // （1）手动释放内存
    //（2）作为对象原型链的终点
    // 作为函数的参数，表示该函数的参数不是一个对象
    let obj1 = 1
    obj1 = null


    // 尽管 null 和 undefined 都表示“没有值”，但它们的用法场景有所不同。
    // 通常来说，null 是由程序员显式赋值的，而 undefined 则通常由 JavaScript 运行时自动生成。
    
    // 这个“误判”也是 JavaScript 作者承认的一个缺陷。在 JavaScript 的早期实现中，值以 32位 存储，
    // 前 3位 表示数据类型的标记，其余位则表示值。在对象的内部表示中，类型标记通常是以一系列零开始的。
    // 而 null 被用来表示空值，类似于 C 语言中的空指针，它的内部表示为全零（即 32 位都是 0），
    // 所以也正是 null 的类型标记与对象的类型标记相同，typeof 操作符将 null 错误地识别为一个对象。

    // null：

    // 初始化空引用：当你创建一个变量，并且你清楚地知道当前不应该指向任何对象或值时，你可以将这个变量设置为 null。比如，你声明了一个用于稍后存放数据库连接的对象，但在建立连接之前，你可以先将它设置为 null。
    // 清空对象引用：如果你有一个对象引用，但你希望删除这个引用，可以将它设置为 null。
    // 函数返回值：在函数中，如果你需要表示“没有返回任何有意义的值”，可以使用 null 作为返回值。
    // 占位符：在某些情况下，null 可以作为占位符，直到你有了实际的值可以放入。

    // undefined：

    // 未初始化的变量：当你声明一个变量但还没有给它赋值时，这个变量的值默认是 undefined。
    // 函数没有返回值：如果你的函数没有使用 return 语句返回任何值，或者 return 语句没有指定任何值，函数的返回值就是 undefined。
    // 属性不存在：当你尝试访问一个对象的属性，而这个属性在对象中不存在时，你得到的是 undefined。
    // 参数未提供：如果一个函数的参数没有被调用时提供，那么这个参数的值是 undefined。


</script>
</html>